package com.toy.core.security.access;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.toy.core.security.Authentication;
import com.toy.core.security.chain.FilterInvocation;
import com.toy.core.security.context.SecurityContextHolder;

/**
 * 1、判断url是否可以匿名访问;
 * 2、判断url是否该用户是否可以访问
 * @author bin.xie
 *
 */
public class FilterSecurityInterceptor implements Filter {
	//~ Static fields/initializers =====================================================================================

    private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied";
    
    //~ Instance fields ================================================================================================
    
    private boolean observeOncePerRequest = true;
    
    private AccessDecisionManager accessDecisionManager;

	public void destroy() {}

	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
			FilterChain filterChain) throws IOException, ServletException {
		FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);
		if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
	            && observeOncePerRequest) {
	            // filter already applied to this request and user wants us to observce
	            // once-per-request handling, so don't re-do security checking
	            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
	        } else {
	            // first time this request being called, so perform security checking
	            if (fi.getRequest() != null) {
	                fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
	            }
	            
	            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	            accessDecisionManager.decide(authentication, fi);
	            try {
	                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
	            } finally {
	                
	            }
	        }
	}

	public void init(FilterConfig arg0) throws ServletException {}

	public void setObserveOncePerRequest(boolean observeOncePerRequest) {
		this.observeOncePerRequest = observeOncePerRequest;
	}

	public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) {
		this.accessDecisionManager = accessDecisionManager;
	}
	 
}
